<template>
  <span style="flex:flex;flex-direction: column;justify-content: center;">
    <el-button v-if="type==='button'" type="primary" plain icon="el-icon-upload2" style="margin-left: 10px;" @click="handleUploadData">{{ text }}</el-button>
    <span v-else-if="type=='text'" class="color-primary common-cursor" @click="handleUploadData">
      {{ text }}<i class="el-icon-upload2" />
    </span>
    <el-tooltip v-else class="item" effect="dark" :content="text" placement="top">
      <el-button circle icon="el-icon-upload2" style="margin-left: 10px;" @click="handleUploadData" />
    </el-tooltip>
    <el-dialog
      :title="title+(hasSpend==0?'':('(已耗时'+hasSpend+'s)'))"
      :visible.sync="dialogVisible"
      custom-class="upload-dialog"
      :show-close="false"
      :before-close="handleClose">
      <el-tabs v-model="activeName">
        <el-tab-pane label="文件选择" name="upload">
          <div class="import-data-contaienr">
            <div class="import-data-contaienr-top">
              <div class="item">
                <div class="item_text">1、下载模板，并按照模板填充数据</div>
                <div class="item_middle" style="border-right: 1px dashed #dedede;">
                  <div class="item_icon">
                    <svg-icon icon-class="docFileTypeExcel" />
                  </div>
                  <div class="item_text">仅支持xls、xlsx模板格式文件下载</div>
                  <export-drop-down
                    type="button"
                    :class-name="className"
                    :accept="['xls', 'xlsx']"
                    :async="true"
                    :list-query="{
                      ...listQuery,
                      template:true
                    }"
                    text="下载模板"
                    :title="title+'示例模板'"
                    style="margin-top:10px" />
                </div>
              </div>
              <div class="item">
                <div class="item_text">2、上传填好的文件</div>
                <div class="item_middle">
                  <div class="item_icon">
                    <svg-icon icon-class="docFileTypeOther" />
                  </div>
                  <div v-if="!selectedFileName" class="item_text">仅支持xls、xlsx格式文件</div>
                  <div v-if="selectedFileName" class="item_text">{{ selectedFileName }}</div>
                  <el-upload
                    style="margin-top:10px"
                    :show-file-list="false"
                    action=""
                    accept=".xls,.xlsx"
                    :auto-upload="false"
                    :on-change="handleUploadChange"
                    :multiple="false">
                    <el-button
                      plain
                      icon="el-icon-upload2"
                      type="primary">
                      <template v-if="!selectedFileName">上传文件</template>
                      <template v-if="selectedFileName">重新上传</template>
                    </el-button>
                  </el-upload>
                </div>
              </div>
            </div>
            <div class="import-data-contaienr-middle">
              <div class="item">
                <div class="label">是否保存原文件：</div>
                <div class="input-container">
                  <el-radio-group v-model="fileSave">
                    <el-radio :label="0">不保存</el-radio>
                    <el-radio :label="1">保存</el-radio>
                  </el-radio-group>
                </div>
              </div>
              <slot name="query" />
            </div>
            <div class="import-data-contaienr-remark">
              <p>仅运行导入*.xls、*.xlsx格式文件</p>
              <p>文件大小不能超过{{ sizeLimit }}MB</p>
              <p class="color-danger">若导入出错，提示“eg XSSF instead of HSSF”，请将excel另存为一份即可</p>
              <slot name="remark" />
            </div>
          </div>
        </el-tab-pane>
        <el-tab-pane label="执行日志" name="log">
          <el-progress v-if="percentageShow" :percentage="percentage" style="margin-bottom: 10px;" :text-inside="true" :stroke-width="20" text-color="#fff" :color="customColors" />
          <div class="import-desc">
            <ol>
              <li v-for="(item,index) in logs" :key="index" :class="item.success?'color-primary' : 'color-danger'">{{ index+1 }}、{{ item.time | formatDate('yyyy-MM-dd hh:mm:ss') }}&nbsp;&nbsp;&nbsp;{{ item.message }}。</li>
            </ol>
            <el-empty v-if="logs.length==0" description="暂无执行日志" />
          </div>
        </el-tab-pane>
      </el-tabs>
      <span v-if="activeName==='upload'" slot="footer" class="dialog-footer">
        <el-button :loading="uploadLoading" type="primary" @click="doImportData">立即导入</el-button>
      </span>
    </el-dialog>
  </span>
</template>
<script>
export default {
  props: {
    className: {
      type: String,
      required: true
    },
    listQuery: {
      type: Object,
      required: false,
      default: () => {
        return {}
      }
    },
    // 类型  图标 按钮 文字
    type: {
      type: String,
      required: false,
      default: 'icon'
    },
    title: {
      type: String,
      default: '数据导入'
    },
    text: {
      type: String,
      default: '导入'
    },
    module: {
      type: String,
      required: false,
      default: ''
    },
    actions: {
      type: Array,
      required: false,
      default: () => {
        return ['importData', 'getImportProcessStatus']
      }
    }
  },
  data() {
    return {
      activeName: 'upload',
      fileSave: 0,
      sizeLimit: 3,
      dialogVisible: false,
      uploadLoading: false,
      uploadLoadingText: '文件上传中...',
      percentage: 0,
      percentageShow: false,
      hasSpend: 0,
      stepStart: 0,
      hasSpendInterval: null,
      realTimeProgressInterval: null,
      logs: [],
      fileSaveUUID: '',
      selectedFile: null,
      selectedFileName: null,
      customColors: [
        { color: '#f56c6c', percentage: 20 },
        { color: '#e6a23c', percentage: 40 },
        { color: '#5cb87a', percentage: 60 },
        { color: '#1989fa', percentage: 80 },
        { color: '#6f7ad3', percentage: 100 }
      ]
    }
  },
  watch: {
    listQuery: (val) => {
    }
  },
  created() {

  },
  methods: {
    handleClose(done) {
      if (this.uploadLoading) {
        this.$modal.msgWarning('当前有未完成的数据导入任务,建议不要关闭对话框')
        this.log('当前有未完成的数据导入任务,建议不要关闭对话框')
      } else {
        this.$confirm('确认关闭？').then(_ => {
          done()
        }).catch(_ => {})
      }
    },
    handleUploadData() {
      this.activeName = 'upload'
      this.selectedFile = null
      this.selectedFileName = null
      this.dialogVisible = true
      this.percentage = 0
      this.hasSpend = 0
      this.logs = []
      this.percentageShow = false
    },
    handleUploadChange(file) {
      this.logs = []
      var ext = file.name.substr(file.name.lastIndexOf('.') + 1)
      var exts = ['xls', 'xlsx']
      if (!exts.includes(ext)) {
        this.$modal.msgWarning('请选择.xls、.xlsx格式文件!')
        this.log('请选择.xls、.xlsx格式文件!')
        return
      }
      const isLt = file.size / 1024 / 1024 < this.sizeLimit
      if (!isLt) {
        this.$modal.msgWarning('文件大小不能超过 ' + this.sizeLimit + 'MB!')
        this.log('文件大小不能超过 ' + this.sizeLimit + 'MB!')
        return
      }
      this.selectedFile = file
      this.selectedFileName = file.name
    },
    doImportData() {
      if (!this.selectedFile) {
        this.$modal.msgWarning('请选择文件!')
        this.log('请选择文件!')
        return
      }
      this.$confirm('您确定要导入【' + this.selectedFileName + '】文件吗, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.uploadLoading = true
        const formData = new FormData()
        formData.append('file', this.selectedFile.raw)
        formData.append('className', this.className)
        formData.append('loading', false)
        formData.append('fileSave', this.fileSave === 1)
        for (var item in this.listQuery) {
          formData.append(item, this.listQuery[item])
        }
        this.activeName = 'log'

        this.log(`您已选择数据文件: ${this.selectedFileName}，上传中...`, true)
        this.stepStart = new Date().getTime()
        this.setStepInterval()

        this.$store.dispatch(this.actions[0], formData).then((res) => {
          this.log(`文件${this.selectedFileName},上传成功,任务ID：${res}`, true)
          this.getImportProcessStatus(res)
          this.realTimeProgressInterval = setInterval(() => {
            this.getImportProcessStatus(res)
          }, 1000)
        }).catch((err) => {
          console.log(err)
          this.uploadLoading = false
          this.log(`文件${this.selectedFileName}，上传失败,原因${err.data ? err.data : err}`)
          this.clearImportProcess()
        })
      }).catch(() => {
      })
    },
    getImportProcessStatus(taskId) {
      this.$store.dispatch(this.actions[1], { taskId: taskId, className: this.className, loading: false }).then(response => {
        var describe = response.describe
        var progress = response.progress
        switch (progress) {
          case 'FINISH':
            this.percentageShow = false
            this.log(describe, true)
            this.clearImportProcess()
            this.uploadLoading = true
            this.log('3s后自动关闭对话框!', true)
            setTimeout(() => {
              this.dialogVisible = false
              this.uploadLoading = false
              this.$emit('success', this.fileSaveUUID)
            }, 3000)
            break
          case 'ERROR':
            this.percentageShow = false
            this.log(describe)
            this.clearImportProcess()
            break
          case 'DOWN':
            this.percentageShow = false
            this.log(`文件下载标识：${describe}`, true)
            this.fileSaveUUID = describe
            break
          case 'PROGRESS':
            this.log(describe, true)
            this.percentage = response.progressValue
            this.percentageShow = true
            break
          default:
            this.percentageShow = false
            this.log(describe, true)
            break
        }
      }).catch((err) => {
        this.log(`获取实时进度,原因${err}`)
        this.clearImportProcess()
      })
    },
    clearImportProcess() {
      this.uploadLoading = false
      if (this.realTimeProgressInterval) {
        clearInterval(this.realTimeProgressInterval)
      }
      if (this.hasSpendInterval) {
        clearInterval(this.hasSpendInterval)
      }
    },
    setStepInterval() {
      this.hasSpendInterval = setInterval(() => {
        this.hasSpend = (new Date().getTime() - this.stepStart) / 1000
      }, 1000)
    },
    log(message, isSuccess = false) {
      this.logs.unshift({
        message: message,
        success: isSuccess,
        time: new Date().getTime()
      })
    }
  }
}
</script>
<style lang="scss">
.upload-dialog{
  width: 600px;
  margin: 100px auto 100px auto !important;
  max-height: calc(100vh - 110px);
  .el-dialog__body{
    height: calc(100% - 60px);
    padding: 0 20px 20px;
    display: flex;
    flex-direction: column;
  }
}
.import-data-contaienr{
  width: 100%;
  margin: 0 auto;
  border: 1px solid #dedede;
  border-radius: 4px;
  padding: 16px 20px;
  box-shadow: 0 1px 2px rgba(17,31,44,.12);
  .import-data-contaienr-top{
    display: flex;
    flex-direction: row;
    .item{
      padding: 16px 0 50px;
      text-align: center;
      flex: 1;
      display: flex;
      flex-direction: column;
      .item_text{
        font-size: 14px;
        color: #111f2c;
      }
      .item_middle{
        margin-top: 27px;
        padding-top: 7px;
      }
      .item_icon{
        svg{
          width: 46px;
          height: 68px;
        }
      }
    }
  }
  .import-data-contaienr-middle{
    padding-bottom: 12px;
    border-bottom: 1px solid #dedede;
    .item{
      display: flex;
      flex-direction: row;
      line-height: 32px;
      height: 32px;
      margin-bottom: 12px;
      .label{
        width: 130px;
      }
      .el-input{
        flex: 1;
      }
    }
  }
  .import-data-contaienr-remark{
    padding-top: 16px;
    p {
      font-size: 12px;
      line-height: 15px;
      color: rgba(17, 31, 44, .56);
    }
  }
}
.import-desc{
    color: #aaa;
    height: calc(100vh - 295px);
    overflow: auto;
    ol{
      padding: 0px;
    }
    li{
      margin-bottom: 8px;
      padding: 0;
    }
  }
</style>
